﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.ServiceProcess;
using System.Text;
using FtpLib;

namespace HsbnFolderSync
{
    public partial class Service1 : ServiceBase
    {

        public Service1()
        {
            try
            {
                InitializeComponent();
                if (!(System.Diagnostics.EventLog.SourceExists("Hsbn_Source")))
                {
                    System.Diagnostics.EventLog.CreateEventSource("Hsbn_Source", "Hsbn_Log");
                }
                eventLog1.Source = "Hsbn_Source";
                eventLog1.Log = "Hsbn_Log";  
            }
            catch (Exception ex)
            {
                TextWriter file = new StreamWriter("D:\\logfile.txt", true);
                file.WriteLine(string.Format("Error Init Service on {0}: {1}",DateTime.Now, ex.Message));
                file.Close();
            }
            
            
        }

        private FtpConnection _ftp;
        private string watchPath = @"d:\HOSOBENHNHAN\";
        public void StartFileSystemWatcher()
        {
            try
            {
                eventLog1.WriteEntry("Start Service");
                FileSystemWatcher watch = new FileSystemWatcher();
                eventLog1.WriteEntry(string.Format("Init FileSystemWatcher for folder {0}", watchPath));
                watch.Path = watchPath;
                //watch.Changed += new FileSystemEventHandler(OnChanged);
                watch.Created += new FileSystemEventHandler(OnCreated);
                watch.Deleted += new FileSystemEventHandler(OnDeleted);
                watch.Renamed += new RenamedEventHandler(OnRenamed);
                watch.EnableRaisingEvents = true;
                watch.IncludeSubdirectories = true;

                _ftp = new FtpConnection("116.193.76.85", "hoangtuan", "healthcare");
                _ftp.Open(); /* Open the FTP connection */
                _ftp.Login(); /* Login using previously provided credentials */
            }
            catch (Exception ex)
            {
                TextWriter file = new StreamWriter("D:\\logfile.txt", true);
                file.WriteLine(string.Format("Error Start FileSystemWatcher on {0}: {1}", DateTime.Now, ex.Message));
                file.Close();
            }
        }

        protected override void OnStart(string[] args)
        {
            try
            {
                StartFileSystemWatcher();
            }
            catch (Exception ex)
            {
                TextWriter file = new StreamWriter("D:\\logfile.txt", true);
                file.WriteLine(string.Format("Error Start Service on {0}: {1}", DateTime.Now, ex.Message));
                file.Close();
            }
        }

        //-------------------------------------------------- 
        private void OnChanged(object source, FileSystemEventArgs e)
        {
            // Specify what is done when a file is changed, created, or deleted. 
            string dir = watchPath + "\\" + e.Name;
            eventLog1.WriteEntry(string.Format("Changed Type: {0};\n File: {1};\n FullPath: {2}", e.ChangeType, e.Name, e.FullPath));
            //if (e.FullPath == dir)
            //{
            //    //Console.WriteLine("Changed File: " + e.FullPath + " " + e.ChangeType);
            //    //eventLog1.WriteEntry("Changed File: " + e.FullPath + " " + e.ChangeType);
            //}

        }

        //-------------------------------------------------- 
        private void OnCreated(object source, FileSystemEventArgs e)
        {
            try
            {
                // Specify what is done when a file is changed, created, or deleted. 
                string dir = watchPath + "\\" + e.Name;
                eventLog1.WriteEntry(string.Format("On Created Event: Changed Type: {0};\n File: {1};\n FullPath: {2}", e.ChangeType, e.Name, e.FullPath));
                //if (e.FullPath == dir)
                //{
                // get the file attributes for file or directory
                FileAttributes attr = File.GetAttributes(e.FullPath);
                //detect whether its a directory or file
                if ((attr & FileAttributes.Directory) != FileAttributes.Directory) //Its a file
                {
                    _ftp.Open(); /* Open the FTP connection */
                    _ftp.Login(); /* Login using previously provided credentials */
                    string[] paths = e.FullPath.Split(new char[] { '\\' });
                    string folPath = e.FullPath.Replace(paths[paths.Length - 1], "");
                    eventLog1.WriteEntry(string.Format("Processing File Path: Upload Folder {0}", folPath));
                    UploadFolder(folPath);
                    _ftp.Close();
                }
                //else //Its a file
                //{
                //    eventLog1.WriteEntry(string.Format("Processing Folder Path: Find Folder: {0}", e.FullPath));
                //    FindFolder(e.FullPath);
                //}
                //Console.WriteLine("Changed File: " + e.FullPath + " " + e.ChangeType);
                //eventLog1.WriteEntry("Changed File: " + e.FullPath + " " + e.ChangeType);
                //}

            }
            catch (Exception ex)
            {
                eventLog1.WriteEntry(string.Format("Error: {0} {1}", ex.Message, ex.StackTrace));
            }
           
        }

        //-------------------------------------------------- 
        private void OnDeleted(object source, FileSystemEventArgs e)
        {
            // Specify what is done when a file is changed, created, or deleted. 
            string dir = watchPath + "\\" + e.Name;
            eventLog1.WriteEntry(string.Format("On Deleted Event: Changed Type: {0};\n File: {1};\n FullPath: {2}", e.ChangeType, e.Name, e.FullPath));
            //if (e.FullPath == dir)
            //{
            //    //Console.WriteLine("Changed File: " + e.FullPath + " " + e.ChangeType);
            //    //eventLog1.WriteEntry("Changed File: " + e.FullPath + " " + e.ChangeType);
            //}

        }

        // ---------------------------------------------------------------------------------- 
        private void OnRenamed(object source, RenamedEventArgs e)
        {
            // Specify what is done when a file is renamed. 
            string dir = watchPath + "\\" + e.Name;
            eventLog1.WriteEntry(string.Format("On Renamed Event: Changed Type: {0};\n Rename File \"{1}\" to \"{2}\";\n FullPath: {3}", e.ChangeType, e.OldName, e.Name, e.FullPath));
            //if (e.FullPath == dir)
            //{
            //    //Console.WriteLine("Renamed File: {0} renamed to {1}", e.OldFullPath, e.FullPath);
            //    //eventLog1.WriteEntry(string.Format("Renamed File: {0} renamed to {1}", e.OldFullPath, e.FullPath));
            //}
        }  


        protected override void OnStop()
        {
            try
            {
                eventLog1.WriteEntry("Stop Service");
                _ftp.Close();
            }
            catch (Exception ex)
            {
                TextWriter file = new StreamWriter("C:\\logfile.txt", true);
                file.WriteLine("Error on Init" + ex.Message);
                file.Close();
            }
            
        }

        private void FindFolder(string folderPaths)
        {
            string[] childfolderPaths = Directory.GetDirectories(folderPaths);
            foreach (var localFolder in childfolderPaths)
            {
                string[] files = Directory.GetFiles(localFolder);
                if (files.Length > 1)
                {
                    //if (localFolder.Contains("MS001 - NGUYEN MINH TAM"))
                    //    UploadFolder(localFolder);
                    //else
                    //{
                        UploadFolder(localFolder);    
                    //}
                    
                }
                else
                {
                    FindFolder(localFolder);
                }
            }
        }

        public void ReadFolder()
        {
            try
            {
                string currDateFolder = DateTime.Now.Day.ToString() + DateTime.Now.Month.ToString() + DateTime.Now.Year.ToString();
                string rootFolder = "D:\\HOSOBENHNHAN\\" + currDateFolder;
                if (Directory.Exists(rootFolder))
                {
                     _ftp.Open(); /* Open the FTP connection */
                    _ftp.Login(); /* Login using previously provided credentials */
                    
                    FindFolder(rootFolder);
                    
                    _ftp.Close();
                }
                    
                else
                    eventLog1.WriteEntry("Folder {0} is not exists");
            }
            catch (Exception ex)
            {
                eventLog1.WriteEntry(string.Format("Error: {0} {1}", ex.Message, ex.StackTrace));
            }
            
        }

        /// <summary>
        /// Upload file bằng FTP
        /// 1. Đọc thư mục theo ngày. Ví dụ: ngày 16-12-2013 thì đặt thư mục là ngày 16-12-2013 (nếu chưa có thì service sẽ tạo thư mục đó)
        /// 2. Service sẽ đọc thông tin thư mục của ngày hôm đó (nếu muốn up bệnh nhân nào thì cứ đưa vào thư mục của ngày hôm đó). 
        ///    Thông tin thư mục bệnh nhân gồm MASO-TEN-TEN_CTY
        /// 3. Với từng thư mục sẽ upload lên server và sinh pass tự động theo định nghĩa MASO-TEN-TEN_CTY_PASS. 
        ///    Còn tại thư mục local sau khi upload thành công sẽ rename thư mục thành MASO-TEN-TEN_CTY_OK (thêm chữ ok đằng sau)
        /// 4. Người quản trị vào trang web đó chọn thư mục up lên và nhấn lưu vào CSDL 
        ///    (Hoặc viết service khác chạy trên VPS sẽ có nhiệm vụ đọc thư mục upload theo ngày lên vào lưu vào CSDL)
        /// 5. Chương trình sẽ đọc thư mục đó và lưu vào CSDL theo thông tin thư mục: Mã số - Tên - Tên cty - Pass và đường dẫn thư mục upload
        /// 6. Kiểm tra đã tồn tại bệnh nhân đó chưa. Nếu chưa thì tạo mới, nếu rồi thì bỏ qua
        /// 7. Chương trình hiển thị ra danh sách bệnh nhân theo thông tin trên và khi chọn bệnh nhân nào thì hiển thị thư mục ảnh của bệnh nhân đó
        /// </summary>
        public void UploadFolder(string localFolder)
        {
            string[] paths = localFolder.Split(new char[] { '\\' });
            string ftpFolder = "/report/results/";
            foreach (var s in paths)
            {
                if (s.Trim().ToLower() == "d:" || s.Trim().ToLower() == "hosobenhnhan")
                    continue;
                ftpFolder += s;
                //Kiểm tra thư mục tồn tại không
                if (!_ftp.DirectoryExists(ftpFolder))
                {
                    try
                    {
                        //Nếu không tồn tại thì tạo mới
                        _ftp.CreateDirectory(ftpFolder);
                    }
                    catch (FtpException e)
                    {
                        eventLog1.WriteEntry(String.Format("FTP Error: {0} {1}", e.ErrorCode, e.Message));
                        //Console.WriteLine(String.Format("FTP Error: {0} {1}", e.ErrorCode, e.Message));
                    }
                }
                _ftp.SetCurrentDirectory(ftpFolder);
                ftpFolder += "/";
            }

            ftpFolder = ftpFolder.Substring(0, ftpFolder.Length - 1);
            //if (ftp.DirectoryExists("/HoSoBenhNhan")) /* check that a directory exists */
            _ftp.SetCurrentDirectory(ftpFolder); /* change current directory */

            //Đọc danh sách file trong local Folder
            string[] files = Directory.GetFiles(localFolder);

            foreach (var file in files)
            {
                paths = file.Split(new char[] { '\\' });
                string fileName = paths[paths.Length - 1];

                //ftp.SetCurrentDirectory(ftpFolder);
                //Kiểm tra trên folder ftp đã có file này chưa
                if (!_ftp.FileExists(ftpFolder + "/" + fileName))  /* check that a file exists */
                {
                    try
                    {
                        //Nếu chưa thì upload lên
                        _ftp.PutFile(file, fileName); /* upload c:\localfile.txt to the current ftp directory as file.txt */
                    }
                    catch (FtpException e)
                    {
                        //Console.WriteLine(String.Format("FTP Error: {0} {1}", e.ErrorCode, e.Message));
                        eventLog1.WriteEntry(String.Format("FTP Error: {0} {1}", e.ErrorCode, e.Message));
                    }
                }

                //do some processing

                //foreach (var dir in ftp.GetDirectories("/incoming/processed"))
                //{
                //    Console.WriteLine(dir.Name);
                //    Console.WriteLine(dir.CreationTime);
                //    foreach (var file in dir.GetFiles())
                //    {
                //        Console.WriteLine(file.Name);
                //        Console.WriteLine(file.LastAccessTime);
                //    }
                //}

            }
        }
    }
}
